package event

import (
	"fmt"
	"sync"
	"time"

	"github.com/google/uuid"
	"gorm.io/driver/sqlite"
	"gorm.io/gorm"
	"gorm.io/gorm/schema"
)

// SoftwareRun 表的结构
type SoftwareRun struct {
	ID        string `gorm:"primaryKey;type:varchar(36)"` // 使用 UUID 作为主键
	StartTime time.Time
	EndTime   time.Time
}

// eventManager 管理事件和软件运行
type eventManager struct {
	events       map[string]*Event
	db           *gorm.DB
	currentRunID string       // 当前软件运行的 ID
	mu           sync.RWMutex // 用于同步对 events 的访问
}

var globalEventManager *eventManager
var globalEventManagerLock sync.Mutex

func GetGlobalEventManager() (*eventManager, error) {
	globalEventManagerLock.Lock()
	defer globalEventManagerLock.Unlock()
	if globalEventManager != nil {
		return globalEventManager, nil
	}
	var err error
	globalEventManager, err = newEventManager(nil)
	return globalEventManager, err
}

// 初始化 EventManager
func newEventManager(db *gorm.DB) (*eventManager, error) {
	var err error
	if db == nil {
		// 初始化 SQLite 数据库
		db, err = gorm.Open(sqlite.Open("./events.db"), &gorm.Config{
			NamingStrategy: schema.NamingStrategy{
				SingularTable: true, // 使用单数表名
			},
		})
		if err != nil {
			return nil, err
		}
	}

	err = db.AutoMigrate(&SoftwareRun{}, &Event{})
	if err != nil {
		return nil, err
	}

	return &eventManager{
		events: make(map[string]*Event),
		db:     db,
	}, nil
}

// 添加事件
func (em *eventManager) add(event *Event) {
	em.mu.Lock()
	defer em.mu.Unlock()

	if event == nil {
		return
	}
	if _, ok := em.events[event.ID]; ok {
		return
	}

	em.events[event.ID] = event
	// 如果事件结束，保存到数据库
	em.save(event)
}

func (em *eventManager) save(event *Event) {
	if event.Done() {
		event.SoftwareRunID = em.currentRunID
		em.db.Create(event)
		delete(em.events, event.ID)
	}
}

// 获取正在处理的事件
func (em *eventManager) getProcessingEvents() []*Event {
	em.mu.RLock()
	defer em.mu.RUnlock()

	events := make([]*Event, 0)
	for _, event := range em.events {
		if !event.Done() {
			events = append(events, event)
		} else {
			em.save(event)
		}
	}
	return events
}

// 获取给定 ID 的事件
func (em *eventManager) get(id string) (*Event, error) {
	em.mu.RLock()
	defer em.mu.RUnlock()

	if event, exists := em.events[id]; exists {
		return event, nil
	}
	var event Event
	if err := em.db.Where("id = ?", id).First(&event).Error; err != nil {
		return nil, err
	}
	return &event, nil
}

// 获取给定 ID 列表的全部事件
func (em *eventManager) getArray(ids []string) ([]*Event, error) {
	em.mu.RLock()
	defer em.mu.RUnlock()

	events := make([]*Event, 0)
	for _, id := range ids {
		event, err := em.get(id)
		if err != nil {
			return nil, err
		}
		events = append(events, event)
	}
	return events, nil
}

// 获取当前软件运行的所有事件 ID 列表
func (em *eventManager) getCurrentRunIDs() ([]string, error) {
	em.mu.RLock()
	defer em.mu.RUnlock()

	var eventIDs []string
	// 查询内存中的事件
	for id := range em.events {
		eventIDs = append(eventIDs, id)
	}
	// 查询数据库中的事件，只查询ID
	err := em.db.Model(&Event{}).Where("software_run_id = ?", em.currentRunID).
		Pluck("id", &eventIDs).Error
	if err != nil {
		return nil, err
	}
	return eventIDs, nil
}

// 获取给定 runID 的事件数量
func (em *eventManager) getCountForRun(runID string) (int64, error) {
	if runID == "" {
		return 0, fmt.Errorf("invalid runID")
	}

	var count int64
	err := em.db.Model(&Event{}).Where("software_run_id = ?", runID).Count(&count).Error
	if err != nil {
		return 0, err
	}
	return count, nil
}

// 获取给定 runID 的事件，提供偏移量 offset 和获取数量 cnt 参数
func (em *eventManager) getEventsForRun(runID string, offset int, cnt int) ([]*Event, error) {
	if runID == "" || cnt <= 0 {
		return nil, fmt.Errorf("invalid runID = %s or cnt = %d", runID, cnt)
	}

	events := make([]*Event, 0)
	// 查询数据库中的事件
	var dbEvents []Event
	err := em.db.Where("software_run_id = ?", runID).Offset(offset).Limit(cnt).Find(&dbEvents).Error
	if err != nil {
		return nil, err
	}
	for _, event := range dbEvents {
		events = append(events, &event)
	}
	return events, nil
}

// 获取当前软件运行的所有事件
func (em *eventManager) getCurrentRunEvents() ([]*Event, error) {
	em.mu.RLock()
	defer em.mu.RUnlock()

	events := make([]*Event, 0)
	// 获取内存中的事件
	for _, event := range em.events {
		events = append(events, event)
	}
	// 获取数据库中的事件
	var dbEvents []Event
	err := em.db.Where("software_run_id = ?", em.currentRunID).Find(&dbEvents).Error
	if err != nil {
		return nil, err
	}
	for _, event := range dbEvents {
		events = append(events, &event)
	}
	return events, nil
}

// 获取当前软件运行的 ID
func (em *eventManager) getCurrentRunID() string {
	return em.currentRunID
}

// 获取所有 SoftwareRun ID
func (em *eventManager) getAllRunIDs() ([]string, error) {
	runs, err := em.getAllRuns()
	if err != nil {
		return nil, err
	}
	runIDs := make([]string, len(runs))
	for i, run := range runs {
		runIDs[i] = run.ID
	}
	return runIDs, nil
}

func (em *eventManager) getAllRuns() ([]SoftwareRun, error) {
	var runs []SoftwareRun
	err := em.db.Find(&runs).Error
	if err != nil {
		return nil, err
	}
	return runs, nil
}

func (em *eventManager) startNewRun() error {
	// 创建新的 SoftwareRun 记录
	currentRun := SoftwareRun{
		ID:        uuid.New().String(),
		StartTime: time.Now(),
	}
	return em.db.Create(&currentRun).Error
}

func (em *eventManager) BatchAdd(events []*Event) {
	// 把接口切片转成 *Event 切片再落库
	for _, ev := range events {
		em.add(ev)
	}
}

// // 关闭数据库连接
// func (em *eventManager) close() error {
// 	sqlDB, err := em.db.DB()
// 	if err != nil {
// 		return err
// 	}
// 	return sqlDB.Close()
// }
